home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows 95 API Bible
/
Windows 95 API Bible 3 Disc Set.iso
/
Win32 API Bible Book 3 of 3.iso
/
chapte11
/
getring
/
phone.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-28
|
22KB
|
653 lines
#include <windows.h>
#include <windowsx.h>
#include "phone.h"
#include "tapi.h"
#define BUFSIZE 256
#define APIHIVERSION 0x00010028 /* 1.40 */
#define APILOWVERSION 0x00010000 /* 1.0 */
#define EXTHIVERSION 0x00010005 /* 1.5 */
#define EXTLOWVERSION 0x00000009 /* 0.9 */
#define MAX_PHONE 2
#define OWNER 0
#define MONITOR 1
LPCTSTR lpszAppName = "phoneGetRing";
LPCTSTR lpszTitle = "phoneGetRing";
#if defined (WIN32)
#define IS_WIN32 TRUE
#else
#define IS_WIN32 FALSE
#endif
#define IS_NT IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
#define IS_WIN32S IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
#define IS_WIN95 (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
HINSTANCE hInst; // current instance
HWND hWnd; // parent window handle
HWND hListWnd; // listbox
HDC hdc;
TEXTMETRIC tm ;
BOOL RegisterWin95( CONST WNDCLASS* lpwc );
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (hInstance, lpszAppName);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = lpszAppName;
wc.lpszClassName = lpszAppName;
if ( IS_WIN95 )
{
if ( !RegisterWin95( &wc ) )
return( FALSE );
}
else if ( !RegisterClass( &wc ) )
return( FALSE );
hInst = hInstance;
hWnd = CreateWindow( lpszAppName,
lpszTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL,
NULL,
hInstance,
NULL
);
if ( !hWnd )
return( FALSE );
ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );
while( GetMessage( &msg, NULL, 0, 0) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( msg.wParam );
}
BOOL RegisterWin95( CONST WNDCLASS* lpwc )
{
WNDCLASSEX wcex;
wcex.style = lpwc->style;
wcex.lpfnWndProc = lpwc->lpfnWndProc;
wcex.cbClsExtra = lpwc->cbClsExtra;
wcex.cbWndExtra = lpwc->cbWndExtra;
wcex.hInstance = lpwc->hInstance;
wcex.hIcon = lpwc->hIcon;
wcex.hCursor = lpwc->hCursor;
wcex.hbrBackground = lpwc->hbrBackground;
wcex.lpszMenuName = lpwc->lpszMenuName;
wcex.lpszClassName = lpwc->lpszClassName;
// Added elements for Windows 95.
//...............................
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName,
IMAGE_ICON, 16, 16,
LR_DEFAULTCOLOR );
return RegisterClassEx( &wcex );
}
typedef struct tagMYINFO // general application information
{
HPHONEAPP phoneApp; // instance handle TAPI gives back to us through phoneInitialize()
DWORD dwNumDevices; // number of available devices
DWORD dwAPIVersion; // API version the phone supports
DWORD dwExtVersion; // extended version
} MYINFO;
typedef struct tagPHONEINFO // information on an open phone
{
HPHONE hPhone; // handle to the phone as returned by phoneOpen
DWORD dwDeviceID; // device ID of the phone device
DWORD dwRequestID;
char szPhoneName[128]; // the phone's name
}PHONEINFO;
MYINFO myInfo; //instance of MYINFO structure
PHONEINFO myPhoneInfo[MAX_PHONE]; //instance of myPhoneInfo structure
LONG lRet; //return code
char buf[BUFSIZE]; // buffer for debug message
char DataBuf[BUFSIZE]; //get/set data buffer;
DWORD i;
DWORD dwHookSwitchDevs;
DWORD dwLampMode;
DWORD dwRingMode;
DWORD dwRingVolume;
DWORD dwHookSwitchVolume;
DWORD dwPhoneStates;
DWORD dwButtonModes;
DWORD dwButtonStates;
DWORD dwGain;
HICON hIcon;
LONG lRet;
char buf[BUFSIZE];
PHONECAPS* pPhoneCaps;
PHONEBUTTONINFO* pButtonInfo;
VARSTRING* pVarString;
PHONESTATUS* pPhoneStatus;
PHONEEXTENSIONID ext_id;
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_COMMAND :
switch( LOWORD( wParam ) )
{
case IDM_RUN :
pPhoneCaps = (PHONECAPS *) calloc (1, sizeof(PHONECAPS)+1000);
pPhoneCaps->dwTotalSize = sizeof(PHONECAPS) + 1000;
phoneGetDevCaps(myInfo.phoneApp, OWNER, myInfo.dwAPIVersion, myInfo.dwExtVersion, pPhoneCaps);
if (pPhoneCaps->dwNumRingModes > 0)
{
lRet = phoneSetRing(myPhoneInfo[OWNER].hPhone, pPhoneCaps->dwNumRingModes, 150);
if (lRet > 0)
{
myPhoneInfo[OWNER].dwRequestID = lRet;
wsprintf(buf, "phoneSetRing proceeding!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf( buf,"phoneSetRing failed, err=x%lx", lRet);
phoneError(lRet);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
}
else
{
wsprintf( buf,"The phone does not have the capability to set the ring modes.");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
phoneError(lRet);
}
lRet = phoneGetRing(myPhoneInfo[OWNER].hPhone, &dwRingMode, &dwRingVolume);
if (lRet == 0)
{
wsprintf(buf, "phoneGetRing succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
if (dwRingMode == 0)
{
wsprintf(buf, "The phone device is currently not ringing.");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf(buf, "The phone is ringing with a Ring Mode pattern of x%lx", dwRingMode);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
wsprintf(buf, "The phnes's Ring Volume is x%lx", dwRingVolume);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
}
else
{
wsprintf( buf,"phoneGetRing failed, err=x%lx", lRet);
phoneError(lRet);
}
free (pPhoneCaps);
break;
case IDM_EXIT :
for (i = 0; i < myInfo.dwNumDevices; i++)
phoneClose(myPhoneInfo[i].hPhone);
phoneShutdown(myInfo.phoneApp);
DestroyWindow( hWnd );
break;
case IDM_ABOUT :
DialogBox( hInst, "AboutBox", hWnd, (DLGPROC)About );
break;
}
return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
case WM_CREATE :
hdc = GetDC (hWnd) ;
GetTextMetrics (hdc, &tm) ;
ReleaseDC (hWnd, hdc) ;
hListWnd = CreateWindowEx( 0, "listbox",
" ",
WS_CHILD | WS_VISIBLE,
tm.tmAveCharWidth, tm.tmHeight * 3,
tm.tmAveCharWidth * 16 +
GetSystemMetrics (SM_CXVSCROLL),
tm.tmHeight * 5,
hWnd,
NULL,
hInst,
NULL
);
//phoneInitialize
//...............................................
lRet = phoneInitialize(&myInfo.phoneApp, hInst, phoneCallback, lpszAppName, &myInfo.dwNumDevices);
if (lRet == 0)
{
wsprintf(buf, "phoneInitialize succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf( buf,"phoneInitialize failed, err=x%lx",lRet);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
phoneError(lRet);
break;
}
//phoneNegotiateAPIVersion
//...............................................
lRet = phoneNegotiateAPIVersion(myInfo.phoneApp, 0, APILOWVERSION, APIHIVERSION,
&myInfo.dwAPIVersion, &ext_id);
if (lRet == 0)
{
wsprintf(buf, "phoneNegotiateAPIVersion succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf(buf, "phoneNegotiateAPIVersion failed, err=x%lx", lRet);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
phoneError(lRet);
phoneShutdown(myInfo.phoneApp);
break;
}
//phoneNegotiateExtVersion
//...............................................
lRet = phoneNegotiateExtVersion(myInfo.phoneApp, 0, myInfo.dwAPIVersion, EXTLOWVERSION,
EXTHIVERSION, &myInfo.dwExtVersion);
if (lRet == 0)
{
wsprintf(buf, "phoneNegotiateExtVersion succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf(buf, "phoneNegotiateExtVersion failed, err=x%lx", lRet);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
phoneError(lRet);
}
//phoneOpen
//................................................................
for (i = 0; i < myInfo.dwNumDevices; i++)
{
if ( i == 0)
lRet = phoneOpen(myInfo.phoneApp,i,&myPhoneInfo[i].hPhone,
myInfo.dwAPIVersion,0,(DWORD)phoneCallback, PHONEPRIVILEGE_OWNER);
else
lRet = phoneOpen(myInfo.phoneApp,i,&myPhoneInfo[i].hPhone,
myInfo.dwAPIVersion,0,(DWORD)phoneCallback, PHONEPRIVILEGE_MONITOR);
if (lRet == 0)
{
wsprintf(buf, "phoneOpen succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
pPhoneCaps = (PHONECAPS *) calloc (1, sizeof(PHONECAPS)+1000);
pPhoneCaps->dwTotalSize = sizeof(PHONECAPS) + 1000;
phoneGetDevCaps(myInfo.phoneApp,i,
myInfo.dwAPIVersion, myInfo.dwExtVersion, pPhoneCaps);
strcpy(buf, ((LPSTR)(pPhoneCaps)+pPhoneCaps->dwProviderInfoOffset));
strcat( buf, " is the phone providor's name." );
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
strcpy(buf, ((LPSTR)(pPhoneCaps)+pPhoneCaps->dwPhoneNameOffset));
if (i == 0)
{
strcat( buf, " is the phone's name opened with OWNER privilege." );
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
strcat( buf, " is the phone's name opened with MONITOR privilege." );
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
}
else
{
wsprintf( buf,"phoneOpen failed, err=x%lx", lRet);
phoneError(lRet);
break;
}
}
break;
case WM_SIZE:
MoveWindow(hListWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
break;
case WM_DESTROY :
PostQuitMessage(0);
break;
default :
return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
}
return( 0L );
}
/****************************************************************************
FUNCTION: phoneCallback
PURPOSE: callback function handles phone events
****************************************************************************/
LRESULT CALLBACK phoneCallback (DWORD dwDevice, DWORD dwMsg,
DWORD dwCallbackInst, DWORD dwParam1,
DWORD dwParam2,DWORD dwParam3)
{
switch (dwMsg)
{
case PHONE_REPLY:
if (dwParam1 == myPhoneInfo[OWNER].dwRequestID)
if (dwParam2 != 0)
{
wsprintf( buf,"Function failed, err=x%lx", lRet);
phoneError(lRet);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
break;
case PHONE_STATE:
if (dwParam1 == PHONESTATE_RINGMODE)
{
lRet = phoneGetRing(myPhoneInfo[OWNER].hPhone, &dwRingMode, &dwRingVolume);
if (lRet == 0)
{
wsprintf(buf, "phoneGetRing succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
if (dwRingMode == 0)
{
wsprintf(buf, "The phone device is currently not ringing.");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf(buf, "The phone is ringing with a Ring Mode pattern of x%lx", dwRingMode);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
wsprintf(buf, "The phnes's Ring Volume is x%lx", dwRingVolume);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
}
else
{
wsprintf( buf,"phoneGetRing failed, err=x%lx", lRet);
phoneError(lRet);
}
break;
}
if (dwParam1 == PHONESTATE_SPEAKERHOOKSWITCH)
{
lRet = phoneGetHookSwitch(myPhoneInfo[OWNER].hPhone, &dwHookSwitchDevs);
if (lRet == 0)
{
wsprintf(buf, "phoneGetHookSwitch succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
if (dwHookSwitchDevs & PHONEHOOKSWITCHDEV_SPEAKER)
{
wsprintf(buf, "The phone's HookSwitch Speaker is offhook!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf(buf, "The phone's HookSwitch Speaker is onhook!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
}
else
{
wsprintf( buf,"phoneGetHookSwitch failed, err=x%lx", lRet);
phoneError(lRet);
}
break;
}
if (dwParam1 == PHONESTATE_SPEAKERVOLUME)
{
lRet = phoneGetVolume(myPhoneInfo[OWNER].hPhone, PHONEHOOKSWITCHDEV_SPEAKER, &dwHookSwitchVolume);
if (lRet == 0)
{
wsprintf(buf, "phoneGetVolume succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
wsprintf(buf, "The current volume for the Speaker Hookswitch is x%lx", dwHookSwitchVolume);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf( buf,"phoneGetVolume failed, err=x%lx", lRet);
phoneError(lRet);
}
break;
}
if (dwParam1 == PHONESTATE_SPEAKERGAIN)
{
lRet = phoneGetGain(myPhoneInfo[OWNER].hPhone, PHONEHOOKSWITCHDEV_SPEAKER, &dwGain);
if (lRet == 0)
{
wsprintf(buf, "phoneGetGain succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
wsprintf(buf, "The current Gain is x%lx", dwGain);
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf( buf,"phoneGetGain failed, err=x%lx", lRet);
phoneError(lRet);
}
break;
}
if (dwParam1 == PHONESTATE_DISPLAY)
{
pVarString = (VARSTRING *) calloc (1, sizeof(VARSTRING)+1000);
pVarString->dwTotalSize = sizeof(VARSTRING) + 1000;
lRet = phoneGetDisplay(myPhoneInfo[OWNER].hPhone, pVarString);
if (lRet == 0)
{
wsprintf(buf, "phoneGetDisplay succeeded!");
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
strcpy(buf, lpszTitle);
//strcpy(buf, ((LPSTR)(pVarString)+pVarString->dwStringOffset));
strcat( buf, " is the current phone display." );
SendMessage(hListWnd, LB_INSERTSTRING, (WPARAM) -1, (LONG) (LPSTR) buf) ;
}
else
{
wsprintf( buf,"phoneGetDisplay failed, err=x%lx", lRet);
phoneError(lRet);
}
free (pVarString);
break;
}
}
return (TRUE);
}
/****************************************************************************
FUNCTION: phoneError
PURPOSE: phone error messages
****************************************************************************/
void phoneError (LONG lrc)
{
switch (lrc) {
case PHONEERR_INVALAPPHANDLE:
MessageBox (hWnd, "Invalid app handle.", "", MB_OK);
break;
case PHONEERR_BADDEVICEID:
MessageBox (hWnd,"The specified phone device ID is out of range.", "",
MB_OK);
break;
case PHONEERR_INCOMPATIBLEAPIVERSION:
MessageBox (hWnd, "Incompatible API version.", "", MB_OK);
break;
case PHONEERR_INVALBUTTONLAMPID:
MessageBox (hWnd, "Invalid Button Lamp ID.", "", MB_OK);
break;
case PHONEERR_INVALBUTTONMODE:
MessageBox (hWnd, "Invalid Button Mode.", "", MB_OK);
break;
case PHONEERR_INVALBUTTONSTATE:
MessageBox (hWnd, "Invalid Button State", "", MB_OK);
break;
case PHONEERR_INUSE:
MessageBox (hWnd, "Phone in Use.", "", MB_OK);
break;
case PHONEERR_INVALHOOKSWITCHDEV:
MessageBox (hWnd, "Invalid Hookswitch Device.", "", MB_OK);
break;
case PHONEERR_INVALHOOKSWITCHMODE:
MessageBox (hWnd, "Invalid Hookswitch Device Mode.", "", MB_OK);
break;
case PHONEERR_INVALLAMPMODE:
MessageBox (hWnd, "Invalid Lamp Mode.", "", MB_OK);
break;
case PHONEERR_INCOMPATIBLEEXTVERSION:
MessageBox (hWnd, "Incompatible extension version.","", MB_OK);
break;
case PHONEERR_NOMEM:
MessageBox (hWnd, "No memory","", MB_OK);
break;
case PHONEERR_NODRIVER:
MessageBox (hWnd, "No driver loaded", "", MB_OK);
break;
case PHONEERR_RESOURCEUNAVAIL:
MessageBox (hWnd, "Resource overcommittment", "", MB_OK);
break;
case PHONEERR_ALLOCATED:
MessageBox (hWnd, "Allocation error", "", MB_OK);
break;
case PHONEERR_INVALDATAID:
MessageBox (hWnd, "The data ID is out of range.", "", MB_OK);
break;
case PHONEERR_INVALDEVICECLASS:
MessageBox (hWnd, "The device class was invalid.", "", MB_OK);
break;
case PHONEERR_INVALPOINTER:
MessageBox (hWnd, "The specified pointer parameter is invalid.",
"", MB_OK);
break;
case PHONEERR_OPERATIONFAILED:
MessageBox (hWnd, "Operation failed.", "", MB_OK);
break;
case PHONEERR_INVALPHONEHANDLE:
MessageBox (hWnd, "Invalid phone handle", "", MB_OK);
break;
case PHONEERR_INVALPHONESTATE :
MessageBox (hWnd, "Invalid call state for this function.", "", MB_OK);
break;
case PHONEERR_INVALPRIVILEGE:
MessageBox (hWnd, "Invalid privilege for this function.", "", MB_OK);
break;
case PHONEERR_NODEVICE:
MessageBox (hWnd, "No associated device for given class",
"", MB_OK);
break;
case PHONEERR_OPERATIONUNAVAIL:
MessageBox (hWnd, "The operation is unavailable",
"", MB_OK);
break;
case PHONEERR_INVALPARAM:
MessageBox(hWnd, "Invalid Paramater", "", MB_OK);
break;
case PHONEERR_INVALRINGMODE:
MessageBox(hWnd, "Invalid Ring Mode", "", MB_OK);
break;
}
}
LRESULT CALLBACK About( HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
if ( LOWORD(wParam) == IDOK
|| LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}